Advanced Debugging
About AdvDbg Consult Train Services Products Tools Community Contact  
欢迎光临 高端调试 登录 | 注册 | FAQ
 
  ACPI调试
Linux内核调试
Windows内核调试
 
  调试战役
调试原理
新工具观察
 
  Linux
Windows Vista
Windows
 
  Linux驱动
WDF
WDM
 
  PCI Express
PCI/PCI-X
USB
无线通信协议
 
  64位CPU
ARM
IA-32
  CPU Info Center
 
  ACPI标准
系统认证
Desktop
服务器
 
  Embedded Linux
嵌入式开发工具
VxWorks
WinCE
嵌入式Windows
 
  格蠹调试套件(GDK)
  格蠹学院
  小朱书店
  老雷的微博
  《软件调试》
  《格蠹汇编》
  《软件调试(第二版)》
沪ICP备11027180号-1

Windows内核

帖子发起人: 一鱼之歌   发起时间: 2009-02-10 20:50 下午   回复: 14

Print Search
帖子排序:    
   2009-02-10, 20:50 下午
vincent 离线,最后访问时间: 2009/9/8 11:10:53 一鱼之歌

发帖数前25位
注册: 2009-02-10
发 贴: 36
请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
大家好,请教个缺页问题

据我查资料(windows internals)如果遇到缺页的时候,就会使用到PFN这个东西

这个东西会记录到所缺的页在页文件中的位置,所以要去读取回来就很容易做到。。

但问题是当我们的PE文件第一次启动的时候,因为用到了内存映射一些延迟技术,,

所以PE文件并没全部装入内存,而只是一部份。

所以就存在这一个这样的页:从来未载入过内存,所以也没被转换出来过的时候,

那当要访问这页的时候是怎么找的呢?难道在程序第一次载入的时候系统就已经填充这个PFN数据库了??

如果这样的话,这个PFN岂不是相当大?

另外问下这个PFN结构会不会给置换换出去

谢谢大家

=------------------
帖子更新:晕死,我理解错了一点,就是以为数据在内存的时候,页表项记录就是 数据的直接物理地址,缺页的时候页表项记录的是PFN索引

NND

IP 地址: 已记录   报告
   2009-02-10, 23:00 下午
Raymond 离线,最后访问时间: 2020/7/3 3:40:25 格蠹老雷

发帖数前10位
注册: 2005-12-19
发 贴: 1,303
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
大体理解你的意思,不过你的表述不是很准确,所以只能先初步回答如下。
首先,PFN(Page Frame Number)是描述物理内存的一种基本方式,相当于把物理内存分成页,每个页给一个编号,这个编号就叫PFN,翻译成中文可以叫页帧编号(《软件调试》P175)。PFN是页的编号,它的值乘以页大小(4KB)就是页的物理地址。二者的换算关系是:
PFN×4KB=页的起始物理地址
物理地址/4KB=这个物理地址的PFN
操作系统是以页为单位来组织物理内存的。因此内存管理器维护着一个全局的“数据库”来管理所有物理内存(页)的PFN,通常称为PFN Database,NT内核中以下全局变量便是用作这个用途的:
nt!MmPfnDatabase
nt!MiPfnBitMap
PFN database本身应该是位于非分页内存上的,也就是它总是位于物理内存中。
然后再说,应用程序的地址空间。系统在创建一个进程时,会为其建立地址空间,实际上就是建立页目录和页表。页目录的每个表项叫PDE,页表的每个表项叫PTE。PDE和PTE都可以与一个内存页对应,如果内存管理器将它们所描述的内存页映射到物理内存,那么便将一个PFN赋予它们。如果要把它们所代表的页交换出去,那么便把它们的PFN收回到PFN数据库中。
举个例子来说,以WinDBG进程为例,windbg.exe模块的起始地址是01000000,使用pte命令观察它:
lkd> !pte 01000000
VA 01000000
PDE at 00000000C0600040 PTE at 00000000C0008000
contains 0000000067233067 contains 800000003B3DB025
pfn 67233 ---DA--UWEV pfn 3b3db ----A--UR-V
这说明,这个虚拟地址已经被映射到物理内存中。对应的物理内存是0x3b3db000。
lkd> !dd 3b3db000 l4
#3b3db000 00905a4d 00000003 00000004 0000ffff
lkd> dd 01000000 l4
01000000 00905a4d 00000003 00000004 0000ffff
再看看WinDBG.exe所对应的另一个虚拟地址:
lkd> !pte 01092000
VA 01092000
PDE at 00000000C0600040 PTE at 00000000C0008490
contains 0000000067233067 contains 0000000000000000
pfn 67233 ---DA--UWEV
这个地址的PTE内容是0,没有PFN赋予它,所以这个虚拟地址所对应的内存页目前没有在物理内存中。

IA-32手册卷3A详细的介绍页机制,《软件调试》的2.7节做了简单介绍。

IP 地址: 已记录   报告
   2009-02-10, 23:41 下午
vincent 离线,最后访问时间: 2009/9/8 11:10:53 一鱼之歌

发帖数前25位
注册: 2009-02-10
发 贴: 36
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
谢谢,这个转换我也明白。

我再举个例子看看,也许我理解得不够深。

如果要打开一个1G大小的PE文件,这时候应该只把程序执行必须的数据映射到物理内存,假设这必须部份为24K,

我想问,剩下的1G-24K的数据是在页面文件中吗?
IP 地址: 已记录   报告
   2009-02-11, 08:52 上午
Raymond 离线,最后访问时间: 2020/7/3 3:40:25 格蠹老雷

发帖数前10位
注册: 2005-12-19
发 贴: 1,303
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
不是的
IP 地址: 已记录   报告
   2009-02-11, 11:59 上午
vincent 离线,最后访问时间: 2009/9/8 11:10:53 一鱼之歌

发帖数前25位
注册: 2009-02-10
发 贴: 36
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
呵,谢谢。觉得应该是不在,那里只是给曾经载入过内存而后又被换出来的页面的驻留的吧。

这PE加载就是用到内存映射技术吧?我一直搞不太明白


这时候如果像上面例子说的,1G-4K就是在硬盘(非页面文件区),进程地址空间直接和硬盘数据关联,中间不需要内存了,是这样吗??

如果是这样,每操作一个字节都得I/0操作呀-_-,那岂不是很慢?想不通了。(总体上,数据无非就只能在硬盘和物理内存,还一些比较小的特殊东西)





IP 地址: 已记录   报告
   2009-02-11, 12:38 下午
Raymond 离线,最后访问时间: 2020/7/3 3:40:25 格蠹老雷

发帖数前10位
注册: 2005-12-19
发 贴: 1,303
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
对于用户态的EXE和DLL是用文件映射的。但是不用每个字节都I/O,因为一旦Page Fault,内存管理器是至少把一个页面的内容加载到物理内存的。
IP 地址: 已记录   报告
   2009-02-11, 13:04 下午
vincent 离线,最后访问时间: 2009/9/8 11:10:53 一鱼之歌

发帖数前25位
注册: 2009-02-10
发 贴: 36
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
呵呵,理解深了点了

再想请教下,上面提到,一旦Page Fault,内存管理器是至少把一个页面的内容加载到物理内存的。

那就是内存管理器有张表(暂且叫做表)记录着PE文件在(硬盘)中的位置?要不 Page Fault的时候他也不知道在哪找

如果是这样的话,那每个进程都得有一张,这张表叫啥?,如果哪里有具体这方面的知识

提示下我也好查下资料

另外感谢 张老师2楼所做的解释,加深了理解,建议IA-32手册很好,可惜是英文,看着吃力
IP 地址: 已记录   报告
   2009-02-11, 21:39 下午
WANGyu 离线,最后访问时间: 2012/9/10 3:34:00 王宇

发帖数前10位
男
注册: 2007-05-08
发 贴: 306
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote

先不需要看 Intel 手册,楼主对操作系统的内存管理没有正确的概念,建议先阅读操作系统教材 —— 例如楼主可能没有分清逻辑地址、虚拟地址/线性地址、物理地址之间的关系。

我简单抛块砖。

1. 在实模式时代,CPU 限定了操作系统的寻址能力为 1MB。段基址左移 4位 累加 16位 偏移地址得出20位的物理地址(实模式下段寻址的上限)。在这种模式下缺乏必要的保护设计也没有高效的内存管理机制。

2. 在保护模式时代,段寄存器的大小并没有变化仍然是16位,而偏移地址的“窗口”扩展到了32位。为了达到 2^32 的寻址能力,此时段寄存器(Selector 选择子)的实际作用是查表(GDT表),通过查表得出那被 Intel 为了兼容 80286 而打散的 32位 基址,累加32位偏移地址之后得出线性地址/虚拟地址(2^32 = 4GB 保护模式下段窗口的上限)如果没有开启分页机制的话,那么这个便是物理地址。

3. 如果开启了分页机制,那么虚拟地址只是一个中间步骤,两级页表结构(PDE、PTE)最终将虚拟地址映射到物理页上,最简单的情况下页的大小是4KB,这就是 Swap 的基本单位。稍加思索便可以想到 —— 保护模式下的段机制可以实现代码段的区分/隔离,页属性也可以实现同样的功能,那么两套机制没有必要同时存在 —— 操作系统的设计者将段机制透明化(即所谓的 Flat Mode),更何况,基于分页机制还可以实现虚拟内存管理,何乐而不为呢?

4. 进程模型内存模型密不可分。进程模型的发展不是一蹴而就的,它大致经历了“单任务模型”、“协作式多任务模型(这是微软设计的...)”、“抢占式多任务模型”等阶段。单任务模型太Easy;协作式模型太善良,对“坏人”没有办法;抢占式模型才考虑的比较全面。那么,抢占式模型的考虑全面又体现在哪里?重点之一就是提高安全性——强调隔离,进程间不互相干扰,各进程的线程平等调度等等等等。而这一切必须要有CPU硬件厂商的支持才行,让我们看看80386是怎么设计和处理的吧:

我们可以从两个角度来分析“多任务”和“保护”之间的关系: 进程管理的角度 && 内存管理的角度。

从进程管理的角度看,问题又分成两个方面——(1)多任务之间需要隔离,这一点段机制能够做到,页机制也能够做到。(2)一个任务地址空间内的Kernel Space和User Space之间也需要隔离,两者缺一不可。

从内存管理的角度看,这是多任务隔离的延伸。因为多任务的隔离迫切需要物理地址隔离作为前提,如果不隔离物理地址,多进程的实现也是混乱的,干扰的。那怎么办?Intel对地址做了抽象,物理地址对应用程序再也不可见了。应用程序享用4GB线性地址空间的一半(Linux为3:1),此时进程间谁也看不见谁,谁也不知道对方的存在,任务切换时就像是对一个进程(线程)的“瞬间冰冻”,等它再醒来的时候它还是会认为自己在独占着CPU、独占着物理地址空间。

5. 再回来看楼主的问题。PE 加载后就是使用自己的 2GB User Space,它根本无法感知(它也不用关心)底下 MM 对内存的实际实现/调度,应用程序可以访问0x0012ff?? 它也可以接着访问 0x7ff????? 至于这两段代码所在的页面在不在物理内存里,根本是它不关心的 —— 唯一的差别就是,在物理内存里的代码执行的快那么一点点(对CPU来说),不在物理内存里的代码执行时引发了 #14,倒页面的过程多花费了一些CPU时间。

6. 想分析 Win32 下 Page Fault 的代码实现资料很多,Hook 一下 0x0E,或是调试内核。



7. 如果想自己编码实践分页机制,资料也非常的多,下面是一个实验(切换页表对应不同的物理页得出不同的结果——BAR / FOO):


IP 地址: 已记录   报告
   2009-02-11, 23:38 下午
vincent 离线,最后访问时间: 2009/9/8 11:10:53 一鱼之歌

发帖数前25位
注册: 2009-02-10
发 贴: 36
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
认真看了,也懂了很多,

现在又提出个疑问。
逻辑地址-——>虚拟/线性地址----->物理地址
这三个地址我觉得我也知道怎么转换,

例如张老师上面演示的例如,查找MZ头,里面一直用到的是虚拟地址。

当时像我们平时用OD看到EIP的值应该就是逻辑地址,但我却用dd 命令后面就跟这个EIP的值查看出来的结果却和也是 一样,

也就是这样

dd xxxxxx和 dd yyyyyyy 查看他们的PFN,然后 再查看物理内存中的值,却是一样的

其中xxxxxx就是虚拟地址,yyyyyyy(逻辑地址)就是EIP寄存器这样看到的值

======================

因为照我理解,想要查看EIP这个地址的值,不是还要经过GDT里面的转换吗?为什么可以像虚拟地址那样直接通过PFN就找出来了

。。。。。。。。乱死,希望能知道我想问的什么。解决这个还有些问题希望大家能帮忙

IP 地址: 已记录   报告
   2009-02-11, 23:52 下午
vincent 离线,最后访问时间: 2009/9/8 11:10:53 一鱼之歌

发帖数前25位
注册: 2009-02-10
发 贴: 36
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
王宇大哥,如果方便的话,留下个即时联络工具,好多请教你,我的学校就一个副教授教我。

把这些人问了个遍,都搔搔头,然后说忘记了。哎。。。。。很郁闷
IP 地址: 已记录   报告
   2009-02-12, 20:33 下午
vincent 离线,最后访问时间: 2009/9/8 11:10:53 一鱼之歌

发帖数前25位
注册: 2009-02-10
发 贴: 36
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
这是我调试虚拟地址转换过程,我也会了,现在想下缺页的时候怎么样,

例如上面张老师的 01092000 这个地址本来是有数据的,但由于很长时间没用

没转换出去到pagefile了,现在我怎么要回来???


lkd> db 1000000
01000000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
01000010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........@.......
01000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
01000030 00 00 00 00 00 00 00 00-00 00 00 00 f0 00 00 00 ................
01000040 0e 1f ba 0e 00 b4 09 cd-21 b8 01 4c cd 21 54 68 ........!..L.!Th
01000050 69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f is program canno
01000060 74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20 t be run in DOS
01000070 6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00 mode....$.......
lkd> !pte 1000000
VA 01000000
PDE at C0300010 PTE at C0004000
contains 2356C067 contains 2F359025
pfn 2356c ---DA--UWEV pfn 2f359 ----A--UREV

lkd> db C0004000
c0004000 25 90 35 2f 25 80 a4 41-25 d0 bf 32 25 e0 ef 16 %.5/%..A%..2%...
c0004010 25 f0 bb 1c 25 00 54 21-00 00 00 00 25 20 ac 3a %...%.T!....% .:
c0004020 25 30 c4 18 25 b0 04 23-00 00 00 00 25 90 6c 25 %0..%..#....%.l%
c0004030 25 b0 5b 48 25 f0 df 25-25 00 7c 2b 25 10 c4 4e %.[H%..%%.|+%..N
c0004040 25 70 5d 36 25 80 15 20-25 90 ed 47 25 a0 3d 4c %p]6%.. %..G%.=L
c0004050 25 a0 c5 28 25 90 fd 41-25 80 b1 1a 25 70 6d 16 %..(%..A%...%pm.
c0004060 25 60 c1 31 25 50 75 3f-25 40 75 38 25 30 b5 14 %`.1%Pu?%@u8%0..
c0004070 25 a0 dc 38 25 90 2c 14-25 80 18 22 00 00 00 00 %..8%.,.%.."....
lkd> dc 2356c000
2356c000 ???????? ???????? ???????? ???????? ????????????????
2356c010 ???????? ???????? ???????? ???????? ????????????????
2356c020 ???????? ???????? ???????? ???????? ????????????????
2356c030 ???????? ???????? ???????? ???????? ????????????????
2356c040 ???????? ???????? ???????? ???????? ????????????????
2356c050 ???????? ???????? ???????? ???????? ????????????????
2356c060 ???????? ???????? ???????? ???????? ????????????????
2356c070 ???????? ???????? ???????? ???????? ????????????????
lkd> !dc 2356c000
#2356c000 2f359025 41a48025 32bfd025 16efe025 %.5/%..A%..2%...
#2356c010 1cbbf025 21540025 00000000 3aac2025 %...%.T!....% .:
#2356c020 18c43025 2304b025 00000000 256c9025 %0..%..#....%.l%
#2356c030 485bb025 25dff025 2b7c0025 4ec41025 %.[H%..%%.|+%..N
#2356c040 365d7025 20158025 47ed9025 4c3da025 %p]6%.. %..G%.=L
#2356c050 28c5a025 41fd9025 1ab18025 166d7025 %..(%..A%...%pm.
#2356c060 31c16025 3f755025 38754025 14b53025 %`.1%Pu?%@u8%0..
#2356c070 38dca025 142c9025 22188025 00000000 %..8%.,.%.."....
lkd> !dc 2f359000
#2f359000 00905a4d 00000003 00000004 0000ffff MZ..............
#2f359010 000000b8 00000000 00000040 00000000 ........@.......
#2f359020 00000000 00000000 00000000 00000000 ................
#2f359030 00000000 00000000 00000000 000000f0 ................
#2f359040 0eba1f0e cd09b400 4c01b821 685421cd ........!..L.!Th
#2f359050 70207369 72676f72 63206d61 6f6e6e61 is program canno
#2f359060 65622074 6e757220 206e6920 20534f44 t be run in DOS
#2f359070 65646f6d 0a0d0d2e 00000024 00000000 mode....$.......

IP 地址: 已记录   报告
   2009-02-12, 23:43 下午
Thomson 离线,最后访问时间: 2013/3/31 11:42:42 Thomson

发帖数前10位
注册: 2008-07-03
发 贴: 211
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
关于mapped file,开始肯定是不会加载到内存的.
每个process 都有一个VAD(Virtual Address Descriptor) tree,里面每个node记录一段memory range,这个memory可以是一个exe file 映射到memory的range,这个node里面还会有一人指向exe file object的reference.
如果exe被 map到内存,页表项也是没有的,在第一次访问出缺页异常,而页表里面没有,就会找到相应的vad node,读出file object里面的内容到内存,这样,这个page fault也就被handle了.

理解不一定对,欢迎补充.
IP 地址: 已记录   报告
   2009-02-13, 01:15 上午
vincent 离线,最后访问时间: 2009/9/8 11:10:53 一鱼之歌

发帖数前25位
注册: 2009-02-10
发 贴: 36
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
哇,这里说到 file object 的reference 是重点,原来是通过这个来找到文件内容

在这里打住算了。再深入就累死。不过我在看雪那边看到一文章 也说在一开始的时候就把程序所有的硬盘空间当虚拟地址的页面文件了,不知道这时候算不算在平时说的page files,可是张老师上面却说了,不是!
IP 地址: 已记录   报告
   2009-02-14, 10:42 上午
Raymond 离线,最后访问时间: 2020/7/3 3:40:25 格蠹老雷

发帖数前10位
注册: 2005-12-19
发 贴: 1,303
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote

 vincent wrote:
在一开始的时候就把程序所有的硬盘空间当虚拟地址的页面文件了,不知道这时候算不算在平时说的page files,可是张老师上面却说了,不是!

这种情况使用的是文件映射,不是专用的页交换文件(.e.g. c:\pagefile.sys)。也正是因为这个原因,像Windows这样的操作系统是不可以完全关闭页机制(Paging)的,即使是禁止了专用的页交换文件(在计算机属性>性能>高级>虚拟内存对话框中可以设置)以后。

前面Thomson说的很对,每个进程有一个VAD树,它是把虚拟内存和磁盘上的映射文件关联起来的关键纽带。

 


IP 地址: 已记录   报告
   2009-02-14, 16:27 下午
vincent 离线,最后访问时间: 2009/9/8 11:10:53 一鱼之歌

发帖数前25位
注册: 2009-02-10
发 贴: 36
Re: 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家
Reply Quote
哇,那就好了,这问题起码在轮廓上得到解决了。可惜是这方面资料太少,不知道是不是不开源原因,还是我没找到。
IP 地址: 已记录   报告
高端调试 » 内核探秘 » Windows内核 » 请求一page fault时候系统如何处理问题,张老师让我发这里请教大家

 
Legal Notice Privacy Statement Corporate Governance Corporate Governance
(C)2004-2020 ADVDBG.ORG All Rights Reserved.